"""
场景管理路由 - 基于组合模式的场景树管理
"""

from typing import List, Optional

from fastapi import APIRouter, HTTPException, Query, Depends
from pydantic import BaseModel
from sqlalchemy.orm import Session

from config.database import get_db_session
from pojo.ai_web_scene import (
    AIWebSceneCreate, AIWebSceneUpdate, AIWebSceneResponse,
    AIWebSceneTreeResponse, AIWebSceneQueryParams, SceneStatus
)
from scene.scene_service import SceneService

router = APIRouter()


def get_scene_service(db: Session = Depends(get_db_session)) -> SceneService:
    """获取场景服务实例"""
    return SceneService(db)


class SceneMoveRequest(BaseModel):
    """场景移动请求模型"""
    new_parent_id: Optional[str] = None


@router.get("/tree", response_model=AIWebSceneTreeResponse)
async def get_scene_tree(
        scene_name: Optional[str] = Query(None, description="场景名称模糊查询"),
        scene_status: Optional[SceneStatus] = Query(None, description="场景状态"),
        parent_id: Optional[str] = Query(None, description="父节点ID"),
        creator: Optional[str] = Query(None, description="创建人"),
        include_children: bool = Query(True, description="是否包含子节点"),
        max_depth: Optional[int] = Query(None, description="最大查询深度"),
        service: SceneService = Depends(get_scene_service)
):
    """获取场景树结构 - 组合模式核心接口"""
    query_params = AIWebSceneQueryParams(
        scene_name=scene_name,
        scene_status=scene_status,
        parent_id=parent_id,
        creator=creator,
        include_children=include_children,
        max_depth=max_depth
    )

    return service.get_scene_tree(query_params)


@router.get("/", response_model=List[AIWebSceneResponse])
async def get_all_scenes(
        scene_status: Optional[SceneStatus] = Query(None, description="场景状态过滤"),
        service: SceneService = Depends(get_scene_service)
):
    """获取所有场景的扁平列表（兼容旧接口）"""
    query_params = AIWebSceneQueryParams(
        scene_status=scene_status,
        include_children=True
    )

    tree = service.get_scene_tree(query_params)

    # 将树形结构转换为扁平列表
    all_scenes = []
    for root in tree.root_nodes:
        all_scenes.extend(_extract_all_nodes(root))

    return all_scenes


@router.get("/options", response_model=List[dict])
async def get_scene_options(
        scene_status: Optional[SceneStatus] = Query(SceneStatus.ACTIVE, description="场景状态过滤"),
        service: SceneService = Depends(get_scene_service)
):
    """获取场景下拉选项列表 - 用于前端下拉框"""
    query_params = AIWebSceneQueryParams(
        scene_status=scene_status,
        include_children=True
    )

    tree = service.get_scene_tree(query_params)

    # 将树形结构转换为下拉选项格式
    options = []
    for root in tree.root_nodes:
        options.extend(_extract_scene_options(root))

    return options


@router.get("/{scene_id}", response_model=AIWebSceneResponse)
async def get_scene_by_id(
        scene_id: str,
        service: SceneService = Depends(get_scene_service)
):
    """根据ID获取单个场景节点"""
    scene = service.get_scene_by_id(scene_id)
    if not scene:
        raise HTTPException(status_code=404, detail="场景不存在")
    return scene


@router.get("/{parent_id}/children", response_model=List[AIWebSceneResponse])
async def get_children_by_parent_id(
        parent_id: str,
        service: SceneService = Depends(get_scene_service)
):
    """根据父节点ID获取直接子节点列表"""
    children = service.get_children_by_parent_id(parent_id)
    return children


@router.get("/{scene_id}/path", response_model=List[AIWebSceneResponse])
async def get_scene_path(
        scene_id: str,
        service: SceneService = Depends(get_scene_service)
):
    """获取场景路径（面包屑导航）- 从根节点到当前节点的完整路径"""
    path = service.get_scene_path(scene_id)
    if not path:
        raise HTTPException(status_code=404, detail="场景不存在")
    return path


@router.get("/{scene_id}/ancestors", response_model=List[AIWebSceneResponse])
async def get_scene_ancestors(
        scene_id: str,
        service: SceneService = Depends(get_scene_service)
):
    """获取场景的所有祖先节点"""
    path = service.get_scene_path(scene_id)
    if not path:
        raise HTTPException(status_code=404, detail="场景不存在")
    # 返回除当前节点外的所有祖先节点
    return path[:-1] if len(path) > 1 else []


@router.get("/{scene_id}/descendants", response_model=List[AIWebSceneResponse])
async def get_scene_descendants(
        scene_id: str,
        service: SceneService = Depends(get_scene_service)
):
    """获取场景的所有后代节点"""
    scene = service.get_scene_by_id(scene_id)
    if not scene:
        raise HTTPException(status_code=404, detail="场景不存在")

    # 通过树查询获取包含所有子节点的完整树
    query_params = AIWebSceneQueryParams(
        parent_id=scene_id,
        include_children=True
    )
    tree = service.get_scene_tree(query_params)

    # 提取所有后代节点
    descendants = []
    for root in tree.root_nodes:
        descendants.extend(_extract_all_nodes(root))

    return descendants


def _extract_all_nodes(node: AIWebSceneResponse) -> List[AIWebSceneResponse]:
    """递归提取节点树中的所有节点"""
    nodes = [node]
    for child in node.children:
        nodes.extend(_extract_all_nodes(child))
    return nodes


@router.post("/", response_model=AIWebSceneResponse)
async def create_scene(
        scene: AIWebSceneCreate,
        service: SceneService = Depends(get_scene_service)
):
    """创建新场景节点"""
    try:
        return service.create_scene(scene)
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.put("/{scene_id}", response_model=AIWebSceneResponse)
async def update_scene(
        scene_id: str,
        scene: AIWebSceneUpdate,
        service: SceneService = Depends(get_scene_service)
):
    """更新场景节点"""
    try:
        updated_scene = service.update_scene(scene_id, scene)
        if not updated_scene:
            raise HTTPException(status_code=404, detail="场景不存在")
        return updated_scene
    except ValueError as e:
        raise HTTPException(status_code=409, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.post("/{scene_id}/move", response_model=AIWebSceneResponse)
async def move_scene(
        scene_id: str,
        move_request: SceneMoveRequest,
        service: SceneService = Depends(get_scene_service)
):
    """移动场景节点到新的父节点下"""
    try:
        moved_scene = service.move_scene(scene_id, move_request.new_parent_id)
        if not moved_scene:
            raise HTTPException(status_code=404, detail="场景不存在")
        return moved_scene
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.delete("/{scene_id}")
async def delete_scene(
        scene_id: str,
        service: SceneService = Depends(get_scene_service)
):
    """删除场景节点（级联删除所有子节点）"""
    success = service.delete_scene(scene_id)
    if not success:
        raise HTTPException(status_code=404, detail="场景不存在")
    return {"message": f"场景 {scene_id} 及其所有子节点删除成功"}


def _extract_scene_options(node: AIWebSceneResponse, prefix: str = "") -> List[dict]:
    """递归提取场景选项，带层级前缀"""
    options = []

    # 当前节点选项
    display_name = f"{prefix}{node.scene_name}"
    options.append({
        "value": node.scene_id,
        "label": display_name,
        "level": node.node_level,
        "status": node.scene_status,
        "description": node.description
    })

    # 子节点选项（增加缩进前缀）
    child_prefix = prefix + "  "  # 两个空格表示一级缩进
    for child in node.children:
        options.extend(_extract_scene_options(child, child_prefix))

    return options
